﻿using System;

namespace Bundler
{
    using System.IO.Compression;
    using System.Web;

    public static class GzipCompression
    {
        #region Constants and Fields

        public const string Deflate = "deflate";

        public const string Gzip = "gzip";

        #endregion

        #region Public Methods and Operators

        /// <summary>
        /// Compresses a response using gzip
        /// </summary>
        /// <param name="context">
        /// The context.
        /// </param>
        public static void Compress(HttpContext context)
        {
            if(context == null)
                throw new ArgumentNullException("context");

            if (context.Request.UserAgent != null && context.Request.UserAgent.Contains("MSIE 6"))
            {
                return;
            }

            if (IsEncodingAccepted(Gzip))
            {
                context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress);
                SetEncoding(Gzip);
            }
            else if (IsEncodingAccepted(Deflate))
            {
                context.Response.Filter = new DeflateStream(context.Response.Filter, CompressionMode.Compress);
                SetEncoding(Deflate);
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Checks the request headers to see if the specified encoding is accepted by the client.
        /// </summary>
        /// <param name="encoding">
        /// The encoding.
        /// </param>
        /// <returns>
        /// The is encoding accepted.
        /// </returns>
        private static bool IsEncodingAccepted(string encoding)
        {
            if (HttpContext.Current == null)
                return false;

            return HttpContext.Current.Request.Headers["Accept-encoding"] != null && HttpContext.Current.Request.Headers["Accept-encoding"].Contains(encoding);
        }

        /// <summary>
        /// Adds the specified encoding to the response headers.
        /// </summary>
        /// <param name="encoding">
        /// </param>
        private static void SetEncoding(string encoding)
        {
            if (HttpContext.Current == null)
                return;

            HttpContext.Current.Response.AppendHeader("Content-encoding", encoding);
        }

        #endregion
    }
}